package dk.modified.reshary;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Map;

import org.apache.http.Header;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import dk.modified.reshary.GlobalState.TrackerName;

public class UploadActivity extends Activity {

	// TODO
	// FOR UPLOAD WITH YOUTUBE IN THE FUTURE YOU GET THE THUMBNAIL
	// http://img.youtube.com/vi/VIDEO_ID/default.jpg USE 0,1,2,3 for different
	// sizes 0 is the biggest ! :)

	private ImageView image_preview;
	private ExpandableListView image_category;
	private EditText image_description;
	private Button cmd_image_category;
	private Boolean is_group_checked;
	private EditText image_title;
	private ExpandableListAdapter categoryAdapter;
	private ImageButton cmd_send;
	private ImageButton cmd_cancel;
	private ImageButton cmd_rotate_left;
	private ImageButton cmd_rotate_right;
	private Button cmd_network_retry;
	private RelativeLayout network_retry;
	private Uri uri;
	private ProgressBar progressbar;
	private RelativeLayout command_bar_send_pics;
	private LinearLayout rotate_button_container;
	private Bitmap bitmap;
	private final int REQUIRED_IMAGE_SIZE = 800;

	private static ArrayList<Category> newCategoryArr;

	@SuppressWarnings("unchecked")
	@TargetApi(Build.VERSION_CODES.KITKAT)
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_upload);
		Tracker t = ((GlobalState) getApplication())
				.getTracker(TrackerName.APP_TRACKER);
		t.setScreenName("Reshary Upload");
		t.send(new HitBuilders.AppViewBuilder().build());
		getActionBar().setDisplayHomeAsUpEnabled(true);
		String title = getResources().getString(R.string.app_upload_name_two);
		Util.setActionBar(this, title);

		rotate_button_container = (LinearLayout) findViewById(R.id.rotate_button_container);
		cmd_rotate_left = (ImageButton) findViewById(R.id.cmd_rotate_left);
		cmd_rotate_right = (ImageButton) findViewById(R.id.cmd_rotate_right);
		cmd_network_retry = (Button) findViewById(R.id.cmd_network_retry);
		network_retry = (RelativeLayout) findViewById(R.id.network_retry);
		cmd_send = (ImageButton) findViewById(R.id.cmd_send);
		cmd_cancel = (ImageButton) findViewById(R.id.cmd_cancel);
		progressbar = (ProgressBar) findViewById(R.id.image_loader);
		command_bar_send_pics = (RelativeLayout) findViewById(R.id.command_bar_send_pics);
		image_title = (EditText) findViewById(R.id.image_title);
		image_description = (EditText) findViewById(R.id.image_description);
		image_category = (ExpandableListView) findViewById(R.id.lv_exp_categories_upload);
		cmd_image_category = (Button) findViewById(R.id.cmd_image_category);
		image_preview = (ImageView) findViewById(R.id.image_preview);
		setListeners();

		Intent intent = getIntent();
		Bundle extras = intent.getExtras();
		String action = intent.getAction();
		String type = intent.getType();

		if (savedInstanceState != null) {
			newCategoryArr = savedInstanceState
					.getParcelableArrayList("categoryArr");
			categoryAdapter = new ExpandableListAdapter(UploadActivity.this,
					newCategoryArr);
			image_category.setAdapter(categoryAdapter);
		} else {
			if (getIntent().getParcelableArrayListExtra("categoryArr") != null) {
				newCategoryArr = getIntent().getParcelableArrayListExtra(
						"categoryArr");
				newCategoryArr.remove(0);
				categoryAdapter = new ExpandableListAdapter(
						UploadActivity.this, newCategoryArr);
				image_category.setAdapter(categoryAdapter);
			} else {
				GetCategories();
			}
		}

		if (Intent.ACTION_SEND.equals(action)) {
			if (extras.containsKey(Intent.EXTRA_STREAM)) {
			}
			uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
		} else {
			uri = getIntent().getParcelableExtra("imageUri");
		}

		if (type.equals("image/*") || type.equals("image/gif")
				|| type.equals("image/jpeg") || type.equals("image/png")) {
			LoadImage();

		} else if (type.equals("video/*")) {
			Bitmap thumb = ThumbnailUtils.createVideoThumbnail(
					Util.getPath(this, uri),
					MediaStore.Images.Thumbnails.MINI_KIND);
			image_preview.setImageBitmap(thumb);
			progressbar.setVisibility(View.GONE);
			image_preview.setVisibility(View.VISIBLE);
			command_bar_send_pics.setVisibility(View.VISIBLE);
			rotate_button_container.setVisibility(View.VISIBLE);
		}
	}

	public static Bitmap getImageThumbnail(ContentResolver cr, String path)
			throws Exception {

		Cursor ca = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				new String[] { MediaStore.MediaColumns._ID },
				MediaStore.MediaColumns.DATA + "=?", new String[] { path },
				null);
		if (ca != null && ca.moveToFirst()) {
			int id = ca.getInt(ca.getColumnIndex(MediaStore.MediaColumns._ID));
			ca.close();

			return MediaStore.Images.Thumbnails.getThumbnail(cr, id,
					MediaStore.Images.Thumbnails.FULL_SCREEN_KIND, null);
		}

		ca.close();
		return null;

	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == android.R.id.home) {
			finish();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onBackPressed() {
		if (image_category.isShown()) {
			image_category.setVisibility(View.GONE);
			cmd_image_category.setCompoundDrawablesWithIntrinsicBounds(0, 0,
					R.drawable.ic_action_expand, 0);
		}

		else {
			finish();
			overridePendingTransition(R.anim.fadeout, R.anim.fadein);
		}

	}

	private void setListeners() {

		cmd_rotate_left.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				image_preview.setRotation(image_preview.getRotation() - 90);
			}
		});

		cmd_rotate_right.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				image_preview.setRotation(image_preview.getRotation() + 90);
			}
		});

		cmd_network_retry.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				network_retry.setVisibility(View.GONE);
				progressbar.setVisibility(View.VISIBLE);
				GetCategories();
			}
		});

		image_category.setOnGroupClickListener(new OnGroupClickListener() {

			@Override
			public boolean onGroupClick(ExpandableListView parent, View v,
					int groupPosition, long id) {
				Category selectedCategory = newCategoryArr.get(groupPosition);

				if (selectedCategory.hasChild()) {

				} else {
					is_group_checked = true;
					cmd_image_category.setTag(R.id.tag_category,
							selectedCategory);
					cmd_image_category.setText(selectedCategory
							.getCategoryName());
					cmd_image_category.setTextColor(getResources().getColor(
							android.R.color.black));
					image_category.setVisibility(View.GONE);
					cmd_image_category.setCompoundDrawablesWithIntrinsicBounds(
							0, 0, R.drawable.ic_action_expand, 0);
				}
				return false;
			}
		});

		image_category.setOnChildClickListener(new OnChildClickListener() {

			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				CategorySub selectedCategory = newCategoryArr
						.get(groupPosition).getChildAtPosition(childPosition);
				is_group_checked = false;
				cmd_image_category.setTag(R.id.tag_category, selectedCategory);
				cmd_image_category.setText(selectedCategory.getCategoryName());
				cmd_image_category.setTextColor(getResources().getColor(
						android.R.color.black));
				image_category.setVisibility(View.GONE);
				cmd_image_category.setCompoundDrawablesWithIntrinsicBounds(0,
						0, R.drawable.ic_action_expand, 0);

				return false;
			}
		});

		cmd_image_category
				.setOnFocusChangeListener(new OnFocusChangeListener() {

					@Override
					public void onFocusChange(View v, boolean hasFocus) {
						// TODO Auto-generated method stub
						if (!hasFocus) {
							image_category.setVisibility(View.GONE);
							cmd_image_category
									.setCompoundDrawablesWithIntrinsicBounds(0,
											0, R.drawable.ic_action_expand, 0);
						} else {
							cmd_image_category.performClick();

							InputMethodManager imm = (InputMethodManager) UploadActivity.this
									.getSystemService(Activity.INPUT_METHOD_SERVICE);
							imm.hideSoftInputFromWindow(getCurrentFocus()
									.getWindowToken(), 0);
						}

					}
				});

		cmd_image_category.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (image_category.isShown()) {
					cmd_image_category.setCompoundDrawablesWithIntrinsicBounds(
							0, 0, R.drawable.ic_action_expand, 0);
					image_category.setVisibility(View.GONE);
				} else {
					cmd_image_category.setCompoundDrawablesWithIntrinsicBounds(
							0, 0, R.drawable.ic_action_collapse, 0);
					image_category.setVisibility(View.VISIBLE);
				}

			}
		});

		cmd_send.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {

				SharedPreferences sharedpreferences = UploadActivity.this
						.getSharedPreferences("dk.modified.reshary",
								Context.MODE_PRIVATE);
				Long saved_timestamp = sharedpreferences.getLong("timeLock",
						999);
				Long current_timestamp = System.currentTimeMillis() / 1000;
				Long time_diff = current_timestamp - saved_timestamp;

				if ((time_diff) >= 20) {
					if (cmd_image_category.getTag(R.id.tag_category) == null) {
						Toast.makeText(
								UploadActivity.this,
								getResources().getString(
										R.string.hint_image_category),
								Toast.LENGTH_SHORT).show();
						return;
					}
					if (image_title.getText().toString().trim().length() < 5) {
						Toast.makeText(
								UploadActivity.this,
								getResources()
										.getString(R.string.title_message),
								Toast.LENGTH_SHORT).show();
						return;
					}
					Long timestamp = System.currentTimeMillis() / 1000;
					Editor editor = sharedpreferences.edit();
					editor.putLong("timeLock", timestamp);
					editor.commit();

					int imageCategory = 0;
					if (is_group_checked) {
						Category selectedCategory = (Category) cmd_image_category
								.getTag(R.id.tag_category);
						imageCategory = selectedCategory.getCategoryId();
					} else {
						CategorySub selectedCategory = (CategorySub) cmd_image_category
								.getTag(R.id.tag_category);
						imageCategory = selectedCategory.getCategoryId();
					}

					String imageTitle = image_title.getText().toString().trim();
					String imageDescription = image_description.getText()
							.toString().trim();

					if (image_preview.getRotation() != 0) {
						Matrix mat = new Matrix();
						mat.postRotate(image_preview.getRotation());

						new CompressBitmapAndStartUpload(imageCategory,
								imageTitle, imageDescription, mat, getIntent(),
								UploadActivity.this).execute(bitmap);

					} else {
						new CompressBitmapAndStartUpload(imageCategory,
								imageTitle, imageDescription, null,
								getIntent(), UploadActivity.this)
								.execute(bitmap);
					}

				} else {
					time_diff = 20 - time_diff;
					Toast.makeText(
							UploadActivity.this,
							"You must wait an additional " + time_diff
									+ " seconds, before uploading again.",
							Toast.LENGTH_SHORT).show();
				}
				// do something
			}
		});

		cmd_cancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
			}
		});

	}

	public void LoadImage() {
		Runnable r = new Runnable() {
			public void run() {
				try {

					bitmap = decodeUri(UploadActivity.this, uri,
							REQUIRED_IMAGE_SIZE);
					if (bitmap == null) {
						UploadActivity.this.runOnUiThread(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								Toast.makeText(
										UploadActivity.this,
										getResources().getString(
												R.string.upload_error),
										Toast.LENGTH_LONG).show();
								finish();
							}

						});

					} else {

						UploadActivity.this.runOnUiThread(new Runnable() {
							public void run() {
								try {
									image_preview.setRotation(Util.getPhotoRotationDegree(Util
											.getPath(getApplicationContext(),
													uri)));
								} catch (Exception e) {

								}
								image_preview.setImageBitmap(bitmap);
								progressbar.setVisibility(View.GONE);
								image_preview.setVisibility(View.VISIBLE);
								command_bar_send_pics
										.setVisibility(View.VISIBLE);
								rotate_button_container
										.setVisibility(View.VISIBLE);
							}
						});

					}

				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					UploadActivity.this.runOnUiThread(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							Toast.makeText(
									UploadActivity.this,
									getResources().getString(
											R.string.upload_error),
									Toast.LENGTH_LONG).show();
							finish();
						}

					});
				} catch (OutOfMemoryError e) {
					Log.d("TEST", "OUTOFMEMORY");
					System.gc();
					LoadImage();
				}
			}
		};

		new Thread(r).start();
	}

	public void UploadImage(Context c, String image, int categoryid,
			String title, String description) {
		final UploadNotification mNotificationHelper = new UploadNotification(c);
		mNotificationHelper.createNotification();
		int[] screenSize = getScreenSize();
		SharedPreferences sharedpreferences = UploadActivity.this
				.getSharedPreferences("dk.modified.reshary",
						Context.MODE_PRIVATE);
		String userid = sharedpreferences.getString("userid", "null");
		String securitytoken = sharedpreferences.getString("securitytoken",
				"null");
		String uploadImage = image;

		RequestParams params = new RequestParams();
		params.put("userid", userid);
		params.put("securitytoken", securitytoken);
		params.put("shares", "7");
		params.put("width", String.valueOf(screenSize[0]));
		params.put("height", String.valueOf(screenSize[1]));
		params.put("category", String.valueOf(categoryid));
		params.put("title", title);
		params.put("filedata", uploadImage);
		if (uri.getPath() != null) {
			if (uri.getPath().contains("googleusercontent")) {
				params.put("googleimage", uri.getPath());
			}

		}

		if (!description.equals("")) {
			params.put("description", description);
		}

		ResharyRestClient.post("addmedia/", params,
				new AsyncHttpResponseHandler() {

					@Override
					public void onFailure(int arg0, Header[] arg1, byte[] arg2,
							Throwable arg3) {
						// TODO Auto-generated method stub
						mNotificationHelper.completed();

						String text = getResources().getString(
								R.string.upload_fail);

						Toast.makeText(UploadActivity.this, text,
								Toast.LENGTH_LONG).show();
						super.onFailure(arg0, arg1, arg2, arg3);
					}

					@Override
					public void onSuccess(String response) {
						// TODO Auto-generated method stub

						mNotificationHelper.completed();
						String text = getResources().getString(
								R.string.upload_success);

						Toast.makeText(UploadActivity.this, text,
								Toast.LENGTH_LONG).show();
					}

				}, c);
	}

	public int[] getScreenSize() {
		DisplayMetrics metrics = this.getResources().getDisplayMetrics();
		int width = metrics.widthPixels;
		int height = metrics.heightPixels;

		int[] arr = new int[2];
		arr[0] = width;
		arr[1] = height;
		return arr;
	}

	public static Bitmap decodeUri(Context c, Uri uri, final int requiredSize)
			throws FileNotFoundException {
		BitmapFactory.Options o = new BitmapFactory.Options();
		o.inJustDecodeBounds = true;
		BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri),
				null, o);
		int width_tmp = o.outWidth, height_tmp = o.outHeight;
		int scale = 1;

		while (true) {
			if (width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize)
				break;
			width_tmp /= 2;
			height_tmp /= 2;
			scale *= 2;
		}

		BitmapFactory.Options o2 = new BitmapFactory.Options();
		o2.inSampleSize = scale;
		return BitmapFactory.decodeStream(c.getContentResolver()
				.openInputStream(uri), null, o2);
	}

	private void GetCategories() {

		SharedPreferences sharedpreferences = getSharedPreferences(
				"dk.modified.reshary", Context.MODE_PRIVATE);
		String userid = sharedpreferences.getString("userid", "null");
		String securitytoken = sharedpreferences.getString("securitytoken",
				"null");

		RequestParams params = new RequestParams();
		params.put("userid", userid);
		params.put("securitytoken", securitytoken);

		ResharyRestClient.post("requestcategories/", params,
				new AsyncHttpResponseHandler() {

					@Override
					public void onFailure(Throwable error) {
						// TODO Auto-generated method stub
						network_retry.setVisibility(View.VISIBLE);
						progressbar.setVisibility(View.GONE);
					}

					@Override
					public void onSuccess(String content) {
						// TODO Auto-generated method stub
						if (content.contains("Invalid securitytoken")) {
							Util.intentSendBackUser(UploadActivity.this);
						}

						Map<String, Object> postResponse = Util
								.specialformatResponseCategories(content);

						if (postResponse.containsKey("error")) {
							Util.intentSendBackUser(UploadActivity.this);

						} else {
							@SuppressWarnings("unchecked")
							ArrayList<Category> arrOfCategories = (ArrayList<Category>) postResponse
									.get("cat");

							newCategoryArr = arrOfCategories;
							newCategoryArr.remove(0);
							categoryAdapter = new ExpandableListAdapter(
									UploadActivity.this, newCategoryArr);
							image_category.setAdapter(categoryAdapter);
						}
					}

				}, this);
	}

	private class CompressBitmapAndStartUpload extends
			AsyncTask<Bitmap, Void, String> {

		private int imageCategory;
		private String imagetitle;
		private String imageDescription;
		private Matrix m;
		private Intent i;
		private Context c;

		public CompressBitmapAndStartUpload(int imageCategory,
				String imageTitle, String imageDescription, Matrix m, Intent i,
				Context c) {
			this.imageCategory = imageCategory;
			this.imagetitle = imageTitle;
			this.imageDescription = imageDescription;
			this.m = m;
			this.c = c;
			this.i = i;
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			image_preview.setVisibility(View.GONE);
			command_bar_send_pics.setVisibility(View.GONE);
			rotate_button_container.setVisibility(View.GONE);
			progressbar.setVisibility(View.VISIBLE);
		}

		@Override
		protected String doInBackground(Bitmap... bitmap) {
			if (m != null) {
				Bitmap captureBmp = Bitmap.createBitmap(bitmap[0], 0, 0,
						bitmap[0].getWidth(), bitmap[0].getHeight(), m, true);
				bitmap[0].recycle();

				return uploadLogic(captureBmp);

			} else {

				return uploadLogic(bitmap[0]);
			}

		}

		private String uploadLogic(Bitmap bitmap) {

			String image = "";

			if (getContentResolver().getType(uri) != null) {
				if (getContentResolver().getType(uri).equals("image/gif")) {
					try {
						image = Base64.encodeToString(
								Util.getBytesFromFile(new File(Util.getPath(c,
										uri))), 0);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						finish();
					}
				} else {
					image = Util.encodeTobase64(bitmap);
				}
			} else if (i.getType() != null) {
				if (i.getType().equals("image/gif")) {
					try {
						image = Base64.encodeToString(
								Util.getBytesFromFile(new File(Util.getPath(c,
										uri))), 0);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						finish();
					}

				} else {
					image = Util.encodeTobase64(bitmap);
				}

			}

			else {
				image = Util.encodeTobase64(bitmap);
			}

			return image;
		}

		@Override
		protected void onPostExecute(String result) {
			UploadImage(c, result, imageCategory, imagetitle, imageDescription);
			finish();
		}

	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onRestoreInstanceState(savedInstanceState);
		newCategoryArr = savedInstanceState
				.getParcelableArrayList("categoryArr");
		categoryAdapter = new ExpandableListAdapter(UploadActivity.this,
				newCategoryArr);
		image_category.setAdapter(categoryAdapter);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		// TODO Auto-generated method stub
		super.onSaveInstanceState(outState);
		outState.putParcelableArrayList("categoryArr", newCategoryArr);
	}

}
